/* Character.cs

	Infinite Rogue
	By Dan Alexander, Andy Law
	July 2012

	Cross platform roguelike using C#, Mono, WinForms and GDI.
	
	LICENSE: New BSD License
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Drawing;
using InfiniteRogue.AI;

public class Character
{
    private StatSystem _stats;
    private MapCoord pos;
	private List<ulong> _discoveredTiles;
	private string _name;

    public Character()
    {
        pos = new MapCoord();
        Tile = new TileData()
        {
            Character = '@',
            Color = Color.White,
            Discovered = true,
            Type = TileType.Player,
            Tag = Utilities.NextTag()
        };
		
		Description = "a sentient being";
        _stats = new StatSystem();
        _stats.StatChanging += new StatSystem.StatChangedEventHandler(HpLimiterHandler);

        _discoveredTiles = new List<ulong>();
        _discoveredTiles.Add(Tile.Tag);
    }

    void HpLimiterHandler(string stat, int oldVal, ref int newVal)
    {
        if (stat.ToUpper() == StatSystem.HP.ToUpper())
        {
            int minhp = 0;
            int maxhp = Stats[StatSystem.HP_MAX];

            if (newVal > maxhp) newVal = maxhp;
            if (newVal < minhp) newVal = minhp;
        }
    }

    public StatSystem Stats
    {
        get
        {
            return _stats;
        }
        private set
        {
            _stats = value;
        }
    }

    public int this[string index]
    {
        get { return Stats[index]; }
        set { Stats[index] = value; }
    }

	public string Name{
		get { return _name; }
		set { _name = value; }
	}
	
	public string Description {
		get { return Tile.Description; }
		set { Tile.Description = value; }
	}

    public TileData Tile { get; set; }

    public int X
    {
        get { return pos.x; }
        set { pos.x = value; }
    }

    public int Y
    {
        get { return pos.y; }
        set { pos.y = value; }
    }

    public int Level
    {
        get { return pos.Level; }
        set { pos.Level = value; }
    }

    public MapCoord Pos
    {
        get { return pos; }
    }

	public List<ulong> DiscoveredTiles{
		get { return _discoveredTiles; }
		set { _discoveredTiles = value; }
	}

    public AI AI { get; set; }
	
	public bool HasDiscoveredTile(Tile tile){
		return ( _discoveredTiles.Contains(tile.Tag) );
	}
	
	public bool HasDiscoveredTile(ulong tagToCheck){
		return ( _discoveredTiles.Contains(tagToCheck) );
	}

    public Character LastEnemy { get; set; }

    public void SetCoords(MapCoord coord)
    {
        pos.x = coord.x;
        pos.y = coord.y;
        pos.Level = coord.Level;
    }

    public Color HealthColor
    {
        get
        {
            int maxhp = Stats[StatSystem.HP_MAX];
            int hp = Stats[StatSystem.HP];
            float ratio = (float)hp / (float)maxhp;

            int green = (int)(512f * ratio);
            int red = (int)(512f * -ratio + 512);

            green = green < 0 ? 0 : green > 255 ? 255 : green;
            red = red < 0 ? 0 : red > 255 ? 255 : red;

            return Color.FromArgb(red, green, 0);
        }
    }

    public override string ToString()
    {
        return Name == null ? base.ToString() : Name;
    }
}
